package com.fsoft.core.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;

/**
 * F-Soft 是否为空工具类判断
 * @package com.fsoft.core.utils
 * @author Fish
 * @email it.fish2010@foxmail.com
 * @date 2020-02-18
 * @CopyRight © F-Soft
 **/
@SuppressWarnings(value = { "rawtypes" })
public class OgnlUtils {
	/**
	 * 可以用于判断 Map,Collection,String,Array,Long是否为空
	 * @param o java.lang.Object.
	 * @return boolean.
	 */
	public static boolean isEmpty(Object o) {
		if (o == null)
			return true;
		if (o instanceof String && StringUtils.isBlank((String) o)) {
			return true;
		} else if (o instanceof Collection && ((Collection) o).isEmpty()) {
			return true;
		} else if (o.getClass().isArray() && ((Object[]) o).length == 0) {
			return true;
		} else if (o instanceof Map && ((Map) o).isEmpty()) {
			return true;
		}
		return false;
	}

	/**
	 * 可以用于判断 Map,Collection,String,Array是否不为空
	 * 
	 * @param c
	 * @return
	 */
	public static boolean isNotEmpty(Object o) {
		return !isEmpty(o);
	}

	public static boolean isNotEmptyZero(Object o) {
		return !isEmptyZero(o);
	}

	public static boolean isEmptyZero(Object o) {
		boolean flag = isEmpty(o);
		if (!flag && o instanceof Number) {
			Number val = (Number) o;
			return val.intValue() == 0;
		}
		return flag;
	}

	/**
	 * 首字母转小写
	 * 
	 * @author Fish 2019年3月22日
	 * @param s
	 * @return
	 */
	public static String toLowerCaseFirstChar(String s) {
		if (StringUtils.isBlank(s))
			return null;
		return s.replaceFirst(s.substring(0, 1), s.substring(0, 1).toLowerCase());
	}

	/***
	 * 首字母转大写
	 * 
	 * @USER Fish 2019年3月22日
	 * @param s
	 * @return
	 */
	public static String toUpCaseFirstChar(String s) {
		if (StringUtils.isBlank(s))
			return null;
		return s.replaceFirst(s.substring(0, 1), s.substring(0, 1).toUpperCase());
	}

	/**
	 * 返回一个大写的随机字符串
	 * @user Fish
	 * @date 2019-05-06
	 * @return
	 */
	public static final String randomUpperCaseId() {
		return randomLowerCaseId().toUpperCase();
	}

	/***
	 * 返回小写的随机ID
	 * @user Fish
	 * @date 2019-05-06
	 * @return
	 */
	public static final String randomLowerCaseId() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/*** 密钥算法 */
	private static String KEY_ALGORITHM = "AES";
	/**
	 * 加密-解密算法 / 工作模式 / 填充方式
	 */
	private static String CIPHER_ALGORITHM = "AES/ECB/NoPadding";

	public static final byte[] hexStr2Byte(String hexStr) {
		if (hexStr.length() < 1) {
			return null;
		}
		byte[] result = new byte[hexStr.length() / 2];
		int j = 2;
		for (int i = 0; i < hexStr.length() / j; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

	public static final String byte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	/**
	 * aes 解密
	 * @author Fish
	 * @date 2021-04-25
	 * @param sKey     解密秘钥
	 * @param sSrc     AES加密字符串
	 * @param encoding
	 * @return
	 * @throws Exception
	 */
	public static final String aesDecode(String sKey, String sSrc, String encoding) throws Exception {
		byte[] raw = sKey.getBytes(encoding);
		SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, skeySpec);
		byte[] decryptFrom = hexStr2Byte(sSrc);
		byte[] original = cipher.doFinal(decryptFrom);
		String originalString = new String(original, encoding);
		return originalString;
	}

	/***
	 * AES加密
	 * @author Fish
	 * @date 2021-04-25
	 * @param sKey     秘钥
	 * @param str      原字符串
	 * @param encoding 字符编码
	 * @return
	 * @throws Exception
	 */
	public static String aesEncode(String sKey, String str, String encoding) throws Exception {
		byte[] raw = sKey.getBytes(encoding);
		SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
		byte[] decryptFrom = str.getBytes(encoding);
		byte[] orgs = new byte[16];
		for (int i = 0; i < decryptFrom.length; i++) {
			orgs[i] = decryptFrom[i];
		}
		byte[] original = cipher.doFinal(orgs);
		String originalString = byte2HexStr(original);
		return originalString;
	}

	/**
	 * 获取一个字符串的md5值 注意：这个函数没编码限制
	 * @author fsoft
	 * @date 2021-09-30
	 * @param source
	 * @return
	 */
	public static String md5(String source) {
		if (StringUtils.isBlank(source)) {
			return null;
		}
		byte[] bytes = source.getBytes();
		char[] characters = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		StringBuilder builder = new StringBuilder();
		try {
			MessageDigest messageDigest = MessageDigest.getInstance("md5");
			byte[] targetArr = messageDigest.digest(bytes);

			for (int i = 0; i < targetArr.length; i++) {
				byte b = targetArr[i];

				int lowNum = b & 15;
				int highNum = (b >> 4) & 15;

				char lowChar = characters[lowNum];
				char highChar = characters[highNum];

				builder.append(highChar).append(lowChar);
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return builder.toString();
	}

}
